package edu.mapi.aamas.renderer;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

/**
 * @author RJPG
 *
 * This class makes the conection between obj from neptus and Java3D
 * aplying rotations and translations    
 * 
 * every method ending by "3D" is related with Java3D 
 */
public class Obj3D {
	
	public Point3d destination=null;
	 
	private TransformGroup rotx =new TransformGroup(); //em x
	private TransformGroup roty =new TransformGroup(); // em y
	//private BranchGroup brroty =new BranchGroup();   //node de tudo
	private TransformGroup rotz =new TransformGroup(); //em z
	private TransformGroup move =new TransformGroup(); // trasl
	private TransformGroup model; // "desenho"
	private BranchGroup fullobj=new BranchGroup();   //node de tudo
   
	//private BranchGroup axisobj=new BranchGroup();   //node de tudo
	
	protected double roll=0.,pitch=0.,yaw=0.;  //angulos  
	protected double[] pos=new double[3];      //posi��o
	
	public BranchGroup Axis=new BranchGroup();
	public boolean drawaxis=false;
	public boolean drawlabel=false;
	public boolean drawinfo=false;
	public boolean hide=false;
	
    /**
     * 	constructor all vars set to 0 and no model3D  
     */
    public Obj3D()
	{	
    	// hierarquia
    	fullobj.addChild(move);
    	fullobj.setCapability(BranchGroup.ALLOW_DETACH);
    	//model.addChild(move);
    	move.addChild(rotz);  // transla��o
    	rotz.addChild(rotx);
    	rotx.addChild(roty);   // rota��es
    	roty.addChild(model);  // filho: desenho...
    	
    	// permitir escritas e leituras nos n�s 
    	move.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    	move.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    	move.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
    	
    	rotx.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		rotx.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		
		roty.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		roty.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		roty.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		roty.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
		roty.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		
		rotz.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		rotz.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		rotz.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		rotz.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
		rotz.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		
		//Eixos 
		Axis.addChild(Util3D.makeAxis(true,10.0));
		Axis.setCapability(BranchGroup.ALLOW_DETACH);
		
		
		//move.setPickable(true);// se se implementar o clic em objs
	}
    
    /**
     * @param obj Model 3D to be associated 
     */
    public Obj3D(TransformGroup obj){
    	this();
    	this.setModel3D(obj);
    	
    }
    
    public void DrawAxis(boolean flag)
    {
    	if(flag!=drawaxis)
    	if (!flag)
    	{
    		drawaxis=flag;
    		roty.removeChild(Axis);  // filho: desenho...
    	}
    	else
    	{
    		drawaxis=flag;
    		roty.addChild(Axis);  // filho: desenho...
    	}
    }
    
    /**
     * @param m modelo3D a seleccionar
     */
    public void setModel3D(TransformGroup m){
    	roty.removeChild(model);
    	model=m;   
    	roty.addChild(model); 
    	fullobj.compile();
    }
    
    
    
    /**
     * @return the model associated
     */
    public TransformGroup getModel3D(){
    	return model;
    }
    
    /**
     * @return the full node to be added in Java3D scene
     */
    public BranchGroup getFullObj3D(){
    	return fullobj;
    }
    
    /**
     * @param p set p as node parent of this obj3D
     */
    public void setParent3D(TransformGroup p){
    	p.addChild(fullobj);
    }
    
    /**
     * @param ang roll angle of object
     */
    public void setRoll(double ang)
    {
    	//float rad=(float) ((float)( Math.PI*(ang-roll) )/180.0);//graus to rad
    	//double rad=Math.toRadians(ang);
    	Transform3D rot = new Transform3D();
    	rot.rotX(ang);
    	rotx.setTransform(rot);
    	roll=ang;//
    }

    /**
     * @param ang picth angle of object 
     */
    public void setPitch(double ang)
    {
    	//double rad=Math.toRadians(ang);
    	Transform3D rot = new Transform3D();
    	rot.rotY(ang);
    	roty.setTransform(rot);
    	pitch=ang;//
    }

    /**
     * @param yaw angle of object
     */
    double lastDiff=0;
    public void setYaw(double ang)
    {
    	//double rad=Math.toRadians(ang);
    	double diff=ang-yaw;
    	lastDiff=diff;
    	double roll=diff-lastDiff;
    	roll/=2;
    	setRoll(-diff*2);
    	Transform3D rot = new Transform3D();
    	rot.rotZ(ang);
    	rotz.setTransform(rot);
    	yaw=ang;//
    }
    
    /**
     * @param p vector position p[0]->X->North p[1]->Y->East p[2]->Z->Depth  
     */
    public void setPos(double[] p){
    	Transform3D m = new Transform3D();
    	m.set(new Vector3d(p[0], p[1], p[2]));
    	move.setTransform(m);
    	pos[0]=p[0];//
    	pos[1]=p[1];//
    	pos[2]=p[2];//
    }
    
    public void setPos(Point3d p){
    	Transform3D m = new Transform3D();
    	m.set(new Vector3d(p.x, p.y, p.z));
    	move.setTransform(m);
    	pos[0]=p.x;//
    	pos[1]=p.y;//
    	pos[2]=p.z;//
    }
    
    /**
     * @param c Camera3D is locked on this object
     */
    public void addCamera3D(Camera3D c){
    	//TransformGroup x;
    	//x=(TransformGroup)c.getCamera3D().getParent();
    	//x.removeChild(c.getCamera3D());
    	rotz.addChild(c.getCamera3D());
    }
    
    
    public void addTG(TransformGroup c){
    	//TransformGroup x;
    	//x=(TransformGroup)c.getCamera3D().getParent();
    	//x.removeChild(c.getCamera3D());
    	rotz.addChild(c);
    }
    /**
     * @param c Camera3D is removed
     */
    public void removeCamera3D(Camera3D c){
    	//TransformGroup x;
    	//x=(TransformGroup)c.getCamera3D().getParent();
    	//x.removeChild(c.getCamera3D());
    	rotz.removeChild(c.getCamera3D());
    	//roty.addChild(c.getCamera3D());
    }
}
